/**
 * @FileName: SmsdboProtocol.java
 * @Package: com.ziroom.sms.std.rpc.protocol
 * @author liusq23
 * @created 2017/6/15 下午1:25
 * <p>
 * Copyright 2015 ziroom
 */
package com.ziroom.sms.std.rpc.protocol;

import com.ziroom.sms.std.netty.NettyServer;
import com.ziroom.sms.std.rpc.*;
import com.ziroom.sms.std.rpc.exporter.SmsdboExporter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p></p>
 * <p>
 * <PRE>
 * <BR>	修改记录
 * <BR>-----------------------------------------------
 * <BR>	修改日期			修改人			修改内容
 * </PRE>
 *
 * @author liusq23
 * @version 1.0
 * @since 1.0
 */
public class SmsdboProtocol implements Protocol {

    /**
     * 地址
     */
    private String host;
    /**
     * 端口
     */
    private int port;

    public SmsdboProtocol(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    private Map<String, Exporter> exporterMap = new ConcurrentHashMap<>();

    /**
     * 按照协议，将服务暴露处理
     *
     * @param invoker
     * @param <T>
     * @return
     */
    @Override
    public <T> Exporter<T> exporter(Invoker<T> invoker) throws InterruptedException {
        String key = invoker.getInterface().getName();
        String serviceKey = host + ":" + port + "/" + key;
        SmsdboExporter<T> smsdboExporter = new SmsdboExporter<T>(invoker);
        exporterMap.put(serviceKey, smsdboExporter);
        openServer(host, port);
        return smsdboExporter;
    }

    private void openServer(String host, int port) throws InterruptedException {
        NettyServer nettyServer = new NettyServer();
        nettyServer.open(host, port);
    }

    class SmsdboRpcHandler extends ChannelInboundHandlerAdapter {
        /**
         * @param ctx
         * @param msg
         * @throws Exception
         */
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            if(msg instanceof Invocation){
                Invocation invocation = (Invocation) msg;
                String interfaceName = "";
                String serviceKey = host + ":" + port + "/" + interfaceName;
                Exporter exporter = exporterMap.get(serviceKey);
                Invoker invoker = exporter.getInvoker();
                Object result = invoker.invoke(invocation);
                ctx.writeAndFlush(result);
            }else {
                throw new RPCException("base request");
            }
        }
    }

}
